#pragma once
#include <windows.h>
#include "..\Render\Render.h"
#include <d3d9.h>
#include <d3dx9.h>

class GUI {

public:

	struct tStamp {

		float left;
		float right;
		float top;
		float bottom;
	};

	enum State {

		OPEN,
		OPENING,
		CLOSED,
		CLOSING
	};

	enum MouseButton {

		BUTTON_UP,
		BUTTON_DOWN
	};
	class Components {
public:
		typedef void (*ComponentEvent)(void*, void*); 
	
		class Button {

			static Render::tResource* g_pTemplate;
			GUI::tStamp m_templateStamp;
			std::string m_label;

		public:
			Button();
			virtual ~Button();

			bool Create(const std::string& label);
			bool Release();

			void Draw();
			void Update();
			void OnMouseEvent(const float x, const float y, const GUI::MouseButton left, const GUI::MouseButton right);

			D3DXVECTOR2 Position;
			void* OnClickParam;
			ComponentEvent OnClick;
		};

		class Dialog {
friend class GUI;
			std::vector<GUI::Components::Button> m_Buttons;
			static Render::tResource* g_pTemplate;
			std::string m_message;
			std::string m_title;
			bool m_dispose;

		public:


			Dialog();
			virtual ~Dialog();

			bool Create(const std::string& title, const std::string& message, ComponentEvent OnOK, ComponentEvent OnCancel);
			bool Release();

			void Draw();
			void Update();
			void OnMouseEvent(const float x, const float y, const GUI::MouseButton left, const GUI::MouseButton right);

			D3DXVECTOR2 Position;
			static void OnClose(void*, void*);
		};

	};

private:

	static Render::tResource* g_pCursor;
	static D3DXVECTOR2 g_CursorPosition;
	static GUI::tStamp g_CursorRect;
	static std::vector<GUI::Components::Dialog*> g_Dialogs;

	class Main {

		static D3DXVECTOR2 Position;
		static GUI::tStamp m_MainStamp;
		static Render::tResource* g_pBackgroundBar;
		static std::vector<GUI::Components::Button> g_Buttons;
 
		class Viewer {
			
			static D3DXVECTOR2 Position;
			static GUI::State g_MainState;
			static GUI::tStamp m_MainStamp;
			static Render::tResource* g_pBackground;
			static std::vector<GUI::Components::Button> g_Buttons;
			
			static float g_AnimateOffset;
			static float AnimateDistance();
		public:
			static bool Create();
			static bool Release();	
			static void Draw();
			static void Update();
			static void OnMouseEvent(const float x, const float y, const GUI::MouseButton left, const GUI::MouseButton right);
			static void OnKeydown(UINT* pKeyboardState);
			static void OnToggle(void*, void*);
			static void OnExit(void*, void*);
			static void OnReset(void*, void*);
			
		};

		class Renderer {

			static D3DXVECTOR2 Position;
			static GUI::State g_MainState;
			static GUI::tStamp m_MainStamp;
			static Render::tResource* g_pBackground;
			static std::vector<GUI::Components::Button> g_Buttons;
			
			static float g_AnimateOffset;
			static float AnimateDistance();
		public:
			static bool Create();
			static bool Release();	
			static void Draw();
			static void Update();
			static void OnMouseEvent(const float x, const float y, const GUI::MouseButton left, const GUI::MouseButton right);
			static void OnKeydown(UINT* pKeyboardState);
			static void OnToggle(void*, int);

			
		};

		
	public:
		static bool Create();
		static bool Release();	
		static void Draw();
		static void Update();
		static void OnMouseEvent(const float x, const float y, const GUI::MouseButton left, const GUI::MouseButton right);
		static void OnKeydown(UINT* pKeyboardState);
	};

	static float Width(GUI::tStamp* pRect);
	static float Height(GUI::tStamp* pRect);

	static const uint CONSOLE_LINES;
	static const uint CONSOLE_SPEED;
	static std::string g_Console[];
	static uint g_ConsoleType[];
	static uint g_ConsoleTimer;
	static bool g_CursorEnabled;

public:

	GUI();
	~GUI();

	static bool Create();
	static bool Release();	
	static void Update();
	static void Draw();
	static void DrawConsole();

	static void PokeMouse();
	static void EnableCursor(bool enabled);
	static void OnMouseEvent(const int x, const int y, const GUI::MouseButton left, const GUI::MouseButton right);
	static void OnKeydown(UINT* pKeyboardState);
		
	static void FracToWindow(float x, float y, D3DXVECTOR2* pOutput);
	static void ScaleToWindow(int x, int y, D3DXVECTOR2* pOutput);
	static void StampGetPixel(GUI::tStamp* pStamp, RECT* pOut);
	static void StampGetPercentage(RECT* pStamp, GUI::tStamp* pOut);
	static void StampGetPixel(Render::tResource* pTexture, RECT* pOut);
	static void StampCreate(const int left, const int top, const int width, const int height, RECT* pOut);
	static bool StampContainsPoint(GUI::tStamp* pStamp, D3DXVECTOR2 stampOffset, const float x, const float y);

	static void PrintMessage(const char* format, ...);
	static void PrintWarning(const char* format, ...);
	static void PrintError(const char* format, ...);
};
